package com.xujiang.myblog.network.retrofit;

import android.content.Context;

import com.google.gson.annotations.SerializedName;
import com.trello.rxlifecycle.LifecycleTransformer;
import com.umeng.message.proguard.l;
import com.xujiang.myblog.model.AccessToken;
import com.xujiang.myblog.model.Data;
import com.xujiang.myblog.model.HeadPicture;
import com.xujiang.myblog.model.Login;
import com.xujiang.myblog.model.LoginResult;
import com.xujiang.myblog.model.PreferUser;
import com.xujiang.myblog.model.UserInfo;
import com.xujiang.myblog.netserver.UserService;
import com.xujiang.myblog.network.okhttp.OkHttp3Utils;
import com.xujiang.myblog.util.Callback3;
import com.xujiang.myblog.util.L;
import com.xujiang.myblog.util.UIUtils;
import com.xujiang.myblog.util.Utils;

import java.io.File;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.List;
import java.util.concurrent.TimeUnit;

import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Callback;
import retrofit2.Converter;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.Call;
import retrofit2.http.POST;
import retrofit2.http.Path;
import rx.Observable;
import rx.Subscription;
import rx.schedulers.Schedulers;

/**
 * Created by xujiang on 2017/4/14.
 */

public class MRetrifit {

    private static final String TAG = MRetrifit.class.getSimpleName();


    public interface Service {
        @GET("/")
        Call<String> getResult();
    }

    public static void easyretrifit(String url) {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(url)
                .addConverterFactory( //转换器
                        new Converter.Factory() {
                            @Override
                            public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
                                return new Converter<ResponseBody, String>() {
                                    @Override
                                    public String convert(ResponseBody value) throws IOException {
                                        return value.string();
                                    }
                                };
                            }
                        }).build();    //转换成string  //Converter转换器
        Service service = retrofit.create(Service.class);  //通过反射得到
        Call<String> call = service.getResult();
        call.enqueue(new Callback<String>() {
            @Override
            public void onResponse(Call<String> call, Response<String> response) {

            }

            @Override
            public void onFailure(Call<String> call, Throwable t) {

            }
        });  //异步请求
    }

    public interface Service2 {
//    @GET("/api/cook/list")
//    Call<Tngon> getList(@Query("id") int id,@Query("page") int page,@Query("rows") int rows);

//    @GET("/api/{category}/list")
//    Call<Tngon> getList(@Path("category") String category,@Query("id") int id,@Query("page") int page,@Query("rows") int rows);

        @POST("/api/{category}/list")
        @FormUrlEncoded
        Call<Tngon> getList(@Path("category") String category, @Field("id") int id, @Field("page") int page, @Field("rows") int rows);

    }

    public class Tngon {
        @SerializedName("status")
        private boolean status;
        @SerializedName("total")
        private int total;
        @SerializedName("tngou")
        private List<Cook> list;

        public boolean isStatus() {
            return status;
        }

        public void setStatus(boolean status) {
            this.status = status;
        }

        public int getTotal() {
            return total;
        }

        public void setTotal(int total) {
            this.total = total;
        }

        public List<Cook> getList() {
            return list;
        }

        public void setList(List<Cook> list) {
            this.list = list;
        }
    }


    public class Cook {
        @SerializedName("id")
        private int id;
        @SerializedName("name")
        private String name;//名称
        @SerializedName("food")
        private String food;//食物
        @SerializedName("img")
        private String img;//图片
        @SerializedName("images")
        private String images;//图片
        @SerializedName("description")
        private String description;//描述
        @SerializedName("keywords")
        private String keywords;//关键字
        @SerializedName("message")
        private String message;//资讯内容
        @SerializedName("count")
        private int count;//访问次数
        @SerializedName("fcount")
        private int fcount;//收藏数
        @SerializedName("rcount")
        private int rcount;//评论读数


        public int getRcount() {
            return rcount;
        }

        public void setRcount(int rcount) {
            this.rcount = rcount;
        }

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getFood() {
            return food;
        }

        public void setFood(String food) {
            this.food = food;
        }

        public String getImg() {
            return img;
        }

        public void setImg(String img) {
            this.img = img;
        }

        public String getImages() {
            return images;
        }

        public void setImages(String images) {
            this.images = images;
        }

        public String getDescription() {
            return description;
        }

        public void setDescription(String description) {
            this.description = description;
        }

        public String getKeywords() {
            return keywords;
        }

        public void setKeywords(String keywords) {
            this.keywords = keywords;
        }

        public String getMessage() {
            return message;
        }

        public void setMessage(String message) {
            this.message = message;
        }

        public int getCount() {
            return count;
        }

        public void setCount(int count) {
            this.count = count;
        }

        public int getFcount() {
            return fcount;
        }

        public void setFcount(int fcount) {
            this.fcount = fcount;
        }

    }


    public static void gsonretrifit(String url){
        Retrofit retrofit = new Retrofit
                .Builder()
                .baseUrl(url)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        Service2 service2 = retrofit.create(Service2.class);
        Call<Tngon> list = service2.getList("cook",0, 1, 20);
        list.enqueue(new Callback<Tngon>() {
            @Override
            public void onResponse(Call<Tngon> call, Response<Tngon> response) {

            }

            @Override
            public void onFailure(Call<Tngon> call, Throwable t) {

            }
        });
    }


    /**
     * ----------------------------------------------------------------------------------
     * 上面为demo
     * ----------------------------------------------------------------------------------
     * */
    private Retrofit mLongTimeRetrofit;

    private MRetrifit(){
        OkHttpClient.Builder builder = OkHttp3Utils.get().cloneClient()
                .connectTimeout(5, TimeUnit.SECONDS)  //链接超时
                .writeTimeout(5, TimeUnit.SECONDS)  //写超时
                .readTimeout(5, TimeUnit.MINUTES);  //读超时
        mLongTimeRetrofit = RetrofitUtils.get().getRetrofitBuilder().client(builder.build())
                .build();
    }

    private static MRetrifit client;


    public static synchronized MRetrifit get() {
        if (client == null) {
            synchronized (MRetrifit.class) {
                if (client == null) {
                    client = new MRetrifit();
                }
            }
        }
        return client;
    }


    /***
     * 登录接口
     * @param context {@link Context}
     * @param login       登录信息 (密码MD5后,32位的16进制)
     * @param transformer 生命周期
     * @param callback    回调
     * @return {@link Subscription}
     */
    public Subscription login(final Context context, final Login login,
                              LifecycleTransformer<AccessToken<LoginResult>> transformer,
                              final com.xujiang.myblog.util.Callback<AccessToken<LoginResult>> callback) {
        return Utils.addSubscribe(getLogin(login).compose(transformer),
                new com.xujiang.myblog.util.Callback.EmptyCallback<AccessToken<LoginResult>>() {
                    @Override public void onPreExecute() {
                        callback.onPreExecute();
                    }

                    @Override public void onPostExecute() {
                        callback.onPostExecute();
                    }

                    @Override
                    public void onSuccess(final AccessToken<LoginResult> tAccessToken) {
                        super.onSuccess(tAccessToken);
                        L.i(TAG,tAccessToken.toString());
                        UserInfo userInfo = tAccessToken.getLisTt().get(0).getUserInfo();
                        PreferUser.get().setvalue(userInfo).setPassword(login.getPassword());
                        PreferUser.get().saveInfo(new Callback3.EmptyCallback(){  //保持到本地
                            @Override
                            public void onSuccess() {

                                callback.onSuccess(tAccessToken);
                            }

                            @Override
                            public void onError(Throwable e) {
                                PreferUser.get().clear();
                                UIUtils.showToast(context, "Sign in fail");
                                callback.onError(new Exception(e));
                            }
                        });
                        callback.onSuccess(tAccessToken);
                    }

                    @Override public void onError(Exception e) {
                        callback.onError(e);
                    }
                });
    }


    /***
     * 登录接口
     * @param context {@link Context}
     * @param account       登录用户名
     * @param password       登录用户密码 MD5前
     * @param transformer 生命周期
     * @param callback    回调
     * @return {@link Subscription}
     */
    public Subscription login(final Context context, String account, String password,
                              String devToken, LifecycleTransformer<AccessToken<LoginResult>> transformer,
                              final com.xujiang.myblog.util.Callback<AccessToken<LoginResult>> callback) {
        Login login = new Login(context, account, password, devToken);
        login.md5Password();
        return login(context, login, transformer, callback);
    }




    /**
     * 登录接口 RxJava
     *
     * @param login 登录信息
     * @return {@link Observable}
     */
    public Observable<AccessToken<LoginResult>> getLogin(Login login) {
        return RetrofitUtils.get().getUserService()
                .login(login.getUserId(), login.getPassword(), login)
                .subscribeOn(Schedulers.io());
    }

    /**
     * 注册
     *
     * */
    public void register(Login login, LifecycleTransformer<AccessToken<Data>> transformer,
                         com.xujiang.myblog.util.Callback<AccessToken<Data>> callback){

        Utils.addSubscribe(getRegister(login).compose(transformer), callback);

    }

    public void register(Login login, com.xujiang.myblog.util.Callback<AccessToken<Data>> callback) {
        Utils.addSubscribe(getRegister(login), callback);
    }

    public Observable<AccessToken<Data>> getRegister(Login login) {
        L.i(TAG,login.toString());
        return RetrofitUtils.get().getUserService()
                .register(login.getUserId(), login.getPassword(), login)
                .subscribeOn(Schedulers.io());
    }


    /***
     * 上传头像接口
     *
     * @param file 文件
     * @param callback    回调
     * @return {@link Subscription}
     */
    public Subscription uploadAvatar(File file, com.xujiang.myblog.util.Callback<AccessToken<HeadPicture>> callback) {
        return Utils.addSubscribe(getUploadAvatar(file), callback);
    }


    /**
     * 上传头像接口 RxJava
     *
     * @param file 文件
     * @return {@link Observable}
     */
    public Observable<AccessToken<HeadPicture>> getUploadAvatar(File file) {
        RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
        MultipartBody.Part body = MultipartBody.Part
                .createFormData("file", file.getName(), requestFile);
        Retrofit retrofit = RetrofitUtils.get().getRetrofitBuilder()
                .client(OkHttp3Utils.get().cloneClient().writeTimeout(2, TimeUnit.MINUTES).build())
                .build();
        return retrofit.create(UserService.class).headPortraitUpload(body)
                .subscribeOn(Schedulers.io());
    }

    /**
     *  图片上传接口
     *  @param file 文件
     *  @param  callback 回调
     *
     *  由于上传图片和上传头像结构相同，在这里重用这个类
     *
     */
    public Subscription uploadfile(File file,com.xujiang.myblog.util.Callback<AccessToken<HeadPicture>> callback){
        return Utils.addSubscribe(getUploadPicture(file),callback);
    }


    /**
     * 上传图片接口 RxJava
     *
     * @param file 文件
     * @return {@link Observable}
     */
    public Observable<AccessToken<HeadPicture>> getUploadPicture(File file) {
        RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
        MultipartBody.Part body = MultipartBody.Part
                .createFormData("file", file.getName(), requestFile);
        Retrofit retrofit = RetrofitUtils.get().getRetrofitBuilder()
                .client(OkHttp3Utils.get().cloneClient().writeTimeout(2, TimeUnit.MINUTES).build())
                .build();
        return retrofit.create(UserService.class).PictureUpload(body)
                .subscribeOn(Schedulers.io());
    }


}
